#pragma once
#include <iostream>
#include <vector>

struct NodePoint {
public:
	int x = 0;
	int y = 0;
	char symbol = 'o';
	int obsIndex = -1;				//-1未被访问过，-2障碍物内部点，>=0障碍物轮廓点
	std::vector<int> pathIndex;		//索引代表层数，值代表焊盘的索引编号
	bool isCpt = false;
	bool ocupied = false;			// 记录是否被建立为节点
	int m_node_id = -1;

public:
	NodePoint() {}
	NodePoint(int _x, int _y) : x(_x), y(_y) {}

	double length() {
		return std::sqrt(x * x + y * y);
	}

	double get_distance(NodePoint* other) {
		double M = abs(x - other->x) + abs(y - other->y);	//曼哈顿距离
		double alpha = 0.5;
		double Eu = std::sqrt(double(x - other->x) * (x - other->x) + double(y - other->y) * (y - other->y));	// 欧氏距离
		double beta = 1 - alpha;
		return M * alpha + Eu * beta;
	}

	void set_xy(int x_, int y_) {
		x = x_;
		y = y_;
	}
	NodePoint get_next_pt(const NodePoint& target_pt, int steps, bool round_up = false) {		// 当前点往目标点的方向移动一步（整数点）
		int ex = target_pt.x;
		int ey = target_pt.y;
		if (x == ex && y == ey)
			return target_pt;
		if (x == ex) {		// 横坐标 x 相同，纵坐标 y 递增（或递减）
			return y < ey ? NodePoint(x, y + steps) : NodePoint(x, y - steps);
		}
		if (y == ey) {		// 纵坐标 y 相同，横坐标 x 递增（或递减）
			return x < ex ? NodePoint(x + steps, y) : NodePoint(x - steps, y);
		}
		int newx, newy;
		if (abs(ey - y) > abs(ex - x)) {	// 斜率大于 1, 以 y 递增,否则以x递增
			newy = y + (y < ey ? 1 : -1) * steps;
			double dx = double((ex - x) * (newy - y)) / (ey - y);
			newx = int(x + dx);
			if (round_up && dx != 0)	//向上取整
				newx++;
		}
		else {
			newx = x + (x < ex ? 1 : -1) * steps;
			double dy = double((ey - y) * (newx - x)) / (ex - x);
			newy = int(y + dy);
			if (round_up && dy != 0)	//向上取整
				newy++;
		}
		return NodePoint(newx, newy);
	}
	// 重载输出函数
	friend std::ostream& operator<<(std::ostream& os, const NodePoint& point) {
		os << "(" << point.x << ", " << point.y << ") ";
		return os;
	}

	//重载四则运算符
	NodePoint operator+(const NodePoint& other) const {
		return NodePoint(x + other.x, y + other.y);
	}
	NodePoint operator-(const NodePoint& other) const {
		return NodePoint(x - other.x, y - other.y);
	}
	int operator*(const NodePoint& other) const {
		return x * other.x + y * other.y;
	}
	bool operator==(const NodePoint& other) const {
		return x == other.x && y == other.y;
	}
	bool operator!=(const NodePoint& other) const {
		return x != other.x || y != other.y;
	}
};

struct Pointf {
public:
	double x = 0.0;
	double y = 0.0;

public:
	Pointf() {}
	Pointf(double _x, double _y) : x(_x), y(_y) {}

	double length() {
		return std::sqrt(x * x + y * y);
	}

	//double get_distance(Point* other) {
	//	//return abs(x - other->x) + abs(y - other->y);	//曼哈顿距离
	//	return std::sqrt((x - other->x) * (x - other->x) + (y - other->y) * (y - other->y));	// 欧氏距离
	//}

	void set_xy(int x_, int y_) {
		x = double(x_);
		y = double(y_);
	}

	// 向量单位化
	Pointf normalize() {
		double len = length();
		if (len == 0)
			return Pointf(0, 0);
		else
			return Pointf(x / len, y / len);
	}

	// 重载输出函数
	friend std::ostream& operator<<(std::ostream& os, const Pointf& point) {
		os << "(" << point.x << ", " << point.y << ") ";
		return os;
	}

	//重载四则运算符
	Pointf operator+(const Pointf& other) const {
		return Pointf(x + other.x, y + other.y);
	}
	Pointf operator-(const Pointf& other) const {
		return Pointf(x - other.x, y - other.y);
	}
	double operator*(const Pointf& other) const {
		return x * other.x + y * other.y;
	}
	bool operator==(const Pointf& other) const {
		bool x_eq = std::abs(x - other.x) < 0.0001;
		bool y_eq = std::abs(y - other.y) < 0.0001;
		return x_eq && y_eq;
	}
	bool operator!=(const Pointf& other) const {
		return !(*this == other);
	}
};

